package com.xlfc.registry.zk;

import com.xlfc.common.annotion.SPI;
import com.xlfc.common.config.RpcRequest;
import com.xlfc.common.exception.RpcException;
import com.xlfc.common.extension.ExtensionLoader;
import com.xlfc.cluster.LoadBalance;
import com.xlfc.registry.ServiceConsumer;
import org.apache.curator.framework.CuratorFramework;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.net.InetSocketAddress;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;


public class ZkServiceConsumerImpl implements ServiceConsumer {
    public static final String EXTENSION=LoadBalance.class.getAnnotation(SPI.class).value().trim();//SPI获取EXTENSION
    private static Logger log = LoggerFactory.getLogger(ZkServiceConsumerImpl.class);
    private static Map<String,List<String>> localCache=new ConcurrentHashMap<>();//本地缓存
    @Override
    public InetSocketAddress getIpAndPort(RpcRequest rpcRequest) {
        String rpcServiceName = rpcRequest.getRpcServiceName();
        List<String> serviceUrlList;
        if(!localCache.isEmpty()&&localCache.containsKey(rpcServiceName)){//查缓存
            log.info("--------------走了本地缓存--------------");
            serviceUrlList=localCache.get(rpcServiceName);
        }else{
            CuratorFramework zkClient = ZookeeperUtils.getZkClient();
            serviceUrlList = ZookeeperUtils.getChildrenNodes(zkClient,rpcServiceName);
            if (serviceUrlList==null || serviceUrlList.size()==0){
                throw new RpcException("未找到服务，该服务为："+rpcServiceName);
            }
            localCache.put(rpcServiceName,serviceUrlList);//添加本地缓存
            log.info("--------------走了zk注册中心--------------");
        }

        //负载均衡
        LoadBalance random = ExtensionLoader.getExtensionLoader(LoadBalance.class).getExtension(EXTENSION);
        log.info("--------------使用"+ (EXTENSION.equals("polling")?"轮询":"随机")+"负载均衡--------------");

        String targetServiceUrl = random.selectServiceAddress(serviceUrlList, rpcRequest);

        String[] socketAddressArray = targetServiceUrl.split(":");

        String host = socketAddressArray[0];

        int port = Integer.parseInt(socketAddressArray[1]);

        return new InetSocketAddress(host,port);
    }

}
